<?php

namespace App\Jobs;

use App\Models\Order;
use App\Models\User;
use App\Services\ReportService;
use Illuminate\Filesystem\Cache;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class HtReportApi implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, SerializesModels;

    public $queue = 'ht_report_api';

    public $tries = 5;

    public $timeout = 120;

    protected $service;
    protected $requestData = [];

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(ReportService $reportService)
    {
        $this->service = $reportService;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try{
            /* 判断数据是否有效 */
            if(empty($this->service->orderInfo) || empty($this->service->goodsInfo) || empty($this->service->userInfo)){
                $this->delete();
                throw new \Exception('无效订单');
            }

            if($this->service->requestCode == ReportService::RequestCodeAdd){
                $this->addReport();
            }else if($this->service->requestCode == ReportService::RequestCodePickUp){
                $this->pickupReport();
            }else if($this->service->requestCode == ReportService::RequestCodeRefund){
                $this->refundReport();
            }
            $this->sendReport();

        }catch (\Exception $exception){
            Log::channel('report_api')->info('报表发送失败', ['exception' => $exception]);
            $this->fail($exception->getMessage());
        }

    }


    /*下单数据处理*/
    protected function addReport(){
        $goodsInfo = $this->service->goodsInfo;
        $orderInfo = $this->service->orderInfo;
        $userInfo = $this->service->userInfo;

        $totalOriginPrice = 0;//商品原价总价
        $totalVipPrice = $orderInfo['total_price'];//商品会员价总价
        $totalCouponPrice = $orderInfo['sale_ticket'];//优惠券总价
        $totalFullLessPrice = $orderInfo['full_less'];//满减优惠总价
        $postage = $orderInfo['postage'];//邮费
        $totalPayPrice = $orderInfo['real_pay'];//实际支付价格
        $deductionEightConsh = $orderInfo['deduction_eight_consh'];//八贝币抵扣金额

        $goods = [];$preferential=[];//数据初始化

        foreach($goodsInfo as $k => $good){//循环获取商品原价总价
            $totalPrice = HelpBcmul($good['price'],$good['amount'],2);
            $totalOriginPrice = bcadd($totalOriginPrice,$totalPrice,2);

            if(bccomp($deductionEightConsh,0) > 0){//八贝币
                $preferentialMode = ReportService::EightCash;
                $preferentialPrice = $totalPrice;
                $payPrice = 0;
            }else if(bccomp($good['sale'],1,2) < 0){//会员优惠
                $preferentialMode = ReportService::VIP;
                $preferentialPrice = round(bcsub($totalPrice,$good['total_price'],3),2);//优惠价格
                $payPrice = $good['total_price'];
            }else{
                $preferentialMode = '';
                $preferentialPrice = 0;//优惠价格
                $payPrice = $good['total_price'];
            }

            $goods[] = [
                'goodsCode'         => (string) $good['sku'],// "goodsCode": "商品唯一码",
                'goodsName'         => (string) $good['goods_name'],// "goodsName": "商品名称",
                'productionPlace'   => (string) $this->getOrigin($good['origin']),//"productionPlace": "产地",
                'effect'            => (string) $this->getEffect($good['effect']),//"effect": "功效",
                'num'               => (string) $good['amount'],//"num": "数量",
                'costPrice'         => (string) 0,// "costPrice": "成本价分",  （0）
                'unitPrice'         => (string) $this->precisionMin($good['price']),//"unitPrice": "单价分",  （原价）
                'totalPrice'        => (string) $this->precisionMin($totalPrice),//"totalPrice": "总价",  （原价*个数）
                'preferentialMode'  => (string) $preferentialMode,//"preferentialMode": "优惠方式,说明", （会员）
                'preferentialPrice' => (string) $this->precisionMin($preferentialPrice),//"preferentialPrice": "优惠价格",
                'payPrice'          => (string) $this->precisionMin($payPrice),//"payPrice": "支付价格"
            ];
        }

        //$totalVipPreferentialPrice = bcsub($totalOriginPrice,$totalVipPrice,2);//VIP优惠价格
        $totalPreferentialPrice = bcsub(bcadd($totalOriginPrice,$postage,2),$totalPayPrice,2);//商品总优惠价格 原始+运费-实际支付价格



        /* 优惠方式判断 */
//        if($totalVipPreferentialPrice > 0){
//            $preferential[] = [
//                'mode'  => (string) ReportService::VIP,// "mode": "优惠方式",  （优惠名称）
//                'key'   => (string) ReportService::VIP,// "优惠关键字", （满减，优惠券，会员，八贝币）
//                'price' => (string) $this->precisionMin($totalVipPreferentialPrice),// "价格", （优惠价格 分）
//                'intro' => (string) ReportService::VIP,// "介绍" （优惠说明）
//            ];
//        }
        if($totalFullLessPrice > 0){
            $preferential[] = [
                'mode'  => (string) $orderInfo['activity_name'] ?? '',// "mode": "优惠方式",  （优惠名称）
                'key'   => (string) ReportService::FullReduction,// "优惠关键字", （满减，优惠券，会员，八贝币）
                'price' => (string) $this->precisionMin($totalFullLessPrice),// "价格", （优惠价格 分）
                'intro' => (string) $orderInfo['activity_name'] ?? '',// "介绍" （优惠说明）
            ];
        }
        if($totalCouponPrice > 0){
            $cardName = DB::table('user_reward')->where('order_id',$orderInfo['id'])->value('card_name') ?: '';
            $preferential[] = [
                'mode'  => (string) $cardName,// "mode": "优惠方式",  （优惠名称）
                'key'   => (string) ReportService::Coupon,// "优惠关键字", （满减，优惠券，会员，八贝币）
                'price' => (string) $this->precisionMin($totalCouponPrice),// "价格", （优惠价格 分）
                'intro' => (string) $cardName,// "介绍" （优惠说明）
            ];
        }
        if($deductionEightConsh > 0){
            $preferential[] = [
                'mode'  => (string) ReportService::EightCash,// "mode": "优惠方式",  （优惠名称）
                'key'   => (string) ReportService::EightCash,// "优惠关键字", （满减，优惠券，会员，八贝币）
                'price' => (string) $this->precisionMin($deductionEightConsh),// "价格", （优惠价格 分）
                'intro' => (string) ReportService::EightCash,// "介绍" （优惠说明）
            ];
        }

        $data['order'] = [
            'orderDate'         => (string) $orderInfo['created_at'],
            'city'              => (string) '沈阳',
            'pickupMode'        => (string) $this->pickupMode($orderInfo['send_type']),
            'equipmentCode'     => (string) $orderInfo['machine_code'],
            'pointName'         => (string) $orderInfo['machine_name'],
            'orderCode'         => (string) $orderInfo['online_order'],//订单编号
            'logiName'          => (string) $orderInfo['express_name'],//"logiName": "物流公司",
            'logiCode'          => (string) $orderInfo['express_order'],// "logiCode": "单号",
            'orderStatus'       => (string) $this->orderStatus($orderInfo['status']),// "orderStatus": "1已支付2已取货3已退款",
            'orderPrice'        => (string) $this->precisionMin($totalOriginPrice),// "orderPrice": "订单价格分", ？（原始价格总价）
            'preferentialPrice' => (string) $this->precisionMin($totalPreferentialPrice),// "preferentialPrice": "优惠价格分",
            'payPrice'          => (string) $this->precisionMin($totalPayPrice),//  "payPrice": "支付价格",
            'buyMode'           => (string) $this->buyMode($orderInfo['order_type']),//   "buyMode": "1：机器购买2：小程序",
            'payMode'           => (string) $this->payMode($orderInfo['pay_type']),//  "payMode": "1：支付宝2：微信3:会员4会员微信5巴贝币",
            'payAccount'        => (string) $orderInfo['id'],//"payAccount": "付款账号", ？ （user_id  ）
            'payTime'           => (string) $orderInfo['pay_time'],// "payTime": "2019-04-02 12:00:00",
            'ownerId'           => (string) $this->ownerId($userInfo),//"ownerId": "运营员工ID",     （上级用户）
            'ownerName'         => (string) $this->ownerName($userInfo),//"ownerName": "运营员工名称",
            'userId'            => (string) $userInfo['id'],//"userId": "用户ID",
            'userName'          => (string) $userInfo['realname'],//  "userName": "用户姓名",
            'userType'          => (string) $this->userType($userInfo),//"userType": "用户身份",    （粉丝/会员）
            'userTel'           => (string) $userInfo['phone'],//"userTel": "用户电话",
            'userAddress'       => (string) $this->userAddress($orderInfo),//"userAddress": "用户地址",（地区+address）
            'userBalance'       => (string) $this->precisionMin($userInfo['account']['money_recharge'] ?: 0),//"userBalance": "用户余额分",
            'goods'             => $goods,
            'preferential'      => $preferential,
        ];

        $this->requestData = $data;
    }

    /*取货报表处理*/
    protected function pickupReport(){
        $data['order'] = [
            'orderCode' => (string) $this->service->orderInfo['online_order'],
            'pickupTime'=> (string) $this->service->orderInfo['get_time'],
        ];
        $this->requestData = $data;
    }

    /* 退货报表处理 */
    protected function refundReport(){
        $data['order'] = [
            'orderCode'     => (string) $this->service->orderInfo['online_order'],
            'refundTime'    => (string) $this->service->orderInfo['return_time'],
            'refundPrice'   => (string) $this->precisionMin($this->service->orderInfo['return_money']),
        ];
        $this->requestData = $data;
    }

    /* 获取商品品牌 */
    protected function getBrand($brand){
        $brands = \Illuminate\Support\Facades\Cache::store('redis')->get('report_brand',function(){
            $brands = DB::table('goods_brand')->get(['id','name'])->mapWithKeys(function($item){
                return [$item->id => $item->name];
            });
            \Illuminate\Support\Facades\Cache::put('report_brand',$brands,10);
            return $brands;
        });
        $brandName = $brands[$brand] ?? '';
        return $brandName;
    }

    /* 获取商品产地 */
    protected function getOrigin($origin){
        $origins = \Illuminate\Support\Facades\Cache::store('redis')->get('report_origin',function(){
            $origins = DB::table('goods_origin')->get(['id','name'])->mapWithKeys(function($item){
                return [$item->id => $item->name];
            });
            \Illuminate\Support\Facades\Cache::put('report_origin',$origins,10);
            return $origins;
        });
        $originName = $origins[$origin] ?? '';
        return $originName;
    }

    /* 获取产品功效 */
    protected function getEffect($effect){
        $effectIn = explode(',',$effect);
        $effects = \Illuminate\Support\Facades\Cache::store('redis')->get('report_effect',function(){
            $effects = DB::table('goods_effect')->get(['id','name'])->mapWithKeys(function($item){
                return [$item->id => $item->name];
            });
            \Illuminate\Support\Facades\Cache::put('report_effect',$effects,10);
            return $effects;
        });
        $effectName = '';
        foreach($effectIn as $id){
            if($id && $effects[$id]){
                $effectName .= $effects[$id].',';
            }
        }
        return rtrim($effectName,',');
    }

    protected function sendReport(){
        $requestData = [
            'requestId'     => (string) $this->service->requestId,
            'source'        => (string) 'equipment',//ReportService::Source,
            'requestCode'   => (string) $this->service->requestCode,
            'timestamp'     => (string) time(),
            'data'          => $this->requestData
        ];


        $client = new \GuzzleHttp\Client([
            'base_uri' => $this->service->url,
        ]);

        $response = $client->request('POST', '', [
            'form_params' => [
                'json'  => json_encode($requestData)
            ]
        ]);
        if ($response->getStatusCode() == 200 || $response->getReasonPhrase() == 'OK') {

            $content = \GuzzleHttp\json_decode($response->getBody()->getContents(),true);

            if(App::environment('local')) {
                Log::channel('report_api')->info('发送数据', ['data' => $requestData]);
                Log::channel('report_api')->info('返回数据', ['content' => $content]);
            }

            if($content['code'] == 200){
                $this->delete();
            }else{
                $this->fail($content['message']);
            }

        }else{
            if(App::environment('local')){
                Log::channel('report_api')->info('接口异常', ['data' => $response]);
            }
        }
    }

    /* 获取用户地址 */
    protected function userAddress($order){
        $region = '';
        if($order['user_region'] != ''){
            $regionArr = json_decode($order['user_region'],true);
            $region = implode(' ',$regionArr);
        }
        return $region.' '.$order['user_address'];
    }

    /* 运营员工ID  */
    protected function ownerId($user){
        $ownerId = '';
        if(isset($user['invite_user_info']) && isset($user['invite_user_info']['id']) && $user['invite_user_info']['user_type'] == User::STAFF){
            $ownerId = $user['invite_user_info']['id'];
        }
        return $ownerId;
    }

    /* 运营员工姓名 */
    protected function ownerName($user){
        $ownerName = '';
        if(isset($user['invite_user_info']) && isset($user['invite_user_info']['id']) && $user['invite_user_info']['user_type'] == User::STAFF){
            $ownerName = $user['invite_user_info']['realname'];
        }
        return $ownerName;
    }

    /* 用户等级 */
    protected function userType($user){
        $userType = ReportService::User;
        if(isset($user['account']) && isset($user['account']['user_level_id']) && $user['account']['user_level_id'] != 1){
            $userType = ReportService::VIPUser;
        }
        return $userType;
    }

    /* 订单状态 */
    protected function orderStatus($status){
        $orderStatus = ReportService::OrderStatusPrepaid;

        if($status == Order::STATUS_SUCCESS){
            $orderStatus = ReportService::OrderStatusPicked;
        }else if($status == Order::STATUS_REPAY){
            $orderStatus = ReportService::OrderStatusRefunded;
        }

        return $orderStatus;
    }

    /* 取货方式 */
    protected function pickupMode($send_type){
        return $send_type == Order::SEND_TYPE_EXPRESS ? ReportService::PostMode : ReportService::PickupMode;
    }

    /* 购买方式 */
    protected function buyMode($order_type){
        return $order_type == Order::TYPE_SCANCODE ? ReportService::MachineBuyMode : ReportService::AppBuyMode;
    }

    /* 支付方式 */
    protected function payMode($pay_type){
        $payMode = ReportService::WxPayMode;
        if($pay_type == Order::PAY_TYPE_SELF){
            $payMode = ReportService::BalancePayMode;
        }else if($pay_type == Order::PAY_TYPE_BABEI){
            $payMode = ReportService::EightCashPayMode;
        }
        return $payMode;
    }

    /* 四舍五入高精度除法 */
    protected function bcdiv($left_value,$right_value){
        return numberFormat(bcdiv($left_value,$right_value,3));
    }

    /* 四舍五入高精度乘法 */
    protected function bcmul($left_value,$right_value){
        return numberFormat(bcmul($left_value,$right_value,3));
    }

    /* 精确分 */
    protected function precisionMin($value){
        return bcmul($value,100);
    }
}
